package repository

import (
	"context"
	"fmt"
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
	"techoiceness.com/aiagent/llm-gateway/internal/entity"
)

// conversationRepository 对话仓库实现
type conversationRepository struct {
	db *gorm.DB
}

// NewConversationRepository 创建对话仓库
func NewConversationRepository(db *gorm.DB) ConversationRepository {
	return &conversationRepository{
		db: db,
	}
}

// 对话管理
func (r *conversationRepository) CreateConversation(ctx context.Context, conversation *entity.Conversation) error {
	err := r.db.WithContext(ctx).Create(conversation).Error
	if err != nil {
		return fmt.Errorf("failed to create conversation: %w", err)
	}
	return nil
}

func (r *conversationRepository) GetConversationByID(ctx context.Context, id uuid.UUID) (*entity.Conversation, error) {
	var conversation entity.Conversation
	err := r.db.WithContext(ctx).Where("id = ?", id).First(&conversation).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, fmt.Errorf("failed to get conversation by ID: %w", err)
	}
	return &conversation, nil
}

func (r *conversationRepository) UpdateConversation(ctx context.Context, conversation *entity.Conversation) error {
	err := r.db.WithContext(ctx).Save(conversation).Error
	if err != nil {
		return fmt.Errorf("failed to update conversation: %w", err)
	}
	return nil
}

func (r *conversationRepository) DeleteConversation(ctx context.Context, id uuid.UUID) error {
	err := r.db.WithContext(ctx).Delete(&entity.Conversation{}, "id = ?", id).Error
	if err != nil {
		return fmt.Errorf("failed to delete conversation: %w", err)
	}
	return nil
}

// 用户对话查询
func (r *conversationRepository) GetConversationsByUserID(ctx context.Context, userID uuid.UUID, limit, offset int) ([]entity.Conversation, int64, error) {
	var conversations []entity.Conversation
	var total int64

	query := r.db.WithContext(ctx).Where("user_id = ?", userID)

	// 获取总数
	err := query.Model(&entity.Conversation{}).Count(&total).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to count conversations: %w", err)
	}

	// 获取分页数据
	query = query.Order("updated_at DESC")
	if limit > 0 {
		query = query.Limit(limit)
	}
	if offset > 0 {
		query = query.Offset(offset)
	}

	err = query.Find(&conversations).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to get conversations by user ID: %w", err)
	}

	return conversations, total, nil
}

// 访问权限验证
func (r *conversationRepository) CheckConversationAccess(ctx context.Context, conversationID, userID uuid.UUID) (bool, error) {
	var count int64
	err := r.db.WithContext(ctx).Model(&entity.Conversation{}).
		Where("id = ? AND user_id = ?", conversationID, userID).
		Count(&count).Error
	if err != nil {
		return false, fmt.Errorf("failed to check conversation access: %w", err)
	}
	return count > 0, nil
}

// 对话统计
func (r *conversationRepository) GetConversationCountByUser(ctx context.Context, userID uuid.UUID) (int64, error) {
	var count int64
	err := r.db.WithContext(ctx).Model(&entity.Conversation{}).
		Where("user_id = ?", userID).
		Count(&count).Error
	if err != nil {
		return 0, fmt.Errorf("failed to get conversation count by user: %w", err)
	}
	return count, nil
}

func (r *conversationRepository) GetTotalConversationCount(ctx context.Context) (int64, error) {
	var count int64
	err := r.db.WithContext(ctx).Model(&entity.Conversation{}).Count(&count).Error
	if err != nil {
		return 0, fmt.Errorf("failed to get total conversation count: %w", err)
	}
	return count, nil
}

// 清理操作
func (r *conversationRepository) CleanupOldConversations(ctx context.Context, before time.Time) (int64, error) {
	result := r.db.WithContext(ctx).Where("created_at < ?", before).Delete(&entity.Conversation{})
	if result.Error != nil {
		return 0, fmt.Errorf("failed to cleanup old conversations: %w", result.Error)
	}
	return result.RowsAffected, nil
}

// GetConversationSummary 获取对话摘要
func (r *conversationRepository) GetConversationSummary(ctx context.Context, conversationID uuid.UUID) (*ConversationSummary, error) {
	var result struct {
		Count     int64
		FirstTime time.Time
		LastTime  time.Time
	}

	err := r.db.WithContext(ctx).
		Table("llm_messages").
		Select("COUNT(*) as count, MIN(created_at) as first_time, MAX(created_at) as last_time").
		Where("conversation_id = ?", conversationID).
		Scan(&result).Error

	if err != nil {
		return nil, fmt.Errorf("failed to get conversation summary: %w", err)
	}

	if result.Count == 0 {
		return nil, fmt.Errorf("conversation not found")
	}

	return &ConversationSummary{
		ConversationID: conversationID,
		MessageCount:   result.Count,
		FirstMessage:   result.FirstTime,
		LastMessage:    result.LastTime,
	}, nil
}

// CleanupEmptyConversations 清理空对话
func (r *conversationRepository) CleanupEmptyConversations(ctx context.Context) (int64, error) {
	// 找出所有没有消息的对话ID
	var emptyConversationIDs []uuid.UUID
	err := r.db.WithContext(ctx).
		Raw(`
			SELECT c.id 
			FROM conversations c 
			WHERE NOT EXISTS (
				SELECT 1 FROM llm_messages m WHERE m.conversation_id = c.id
			)
		`).Scan(&emptyConversationIDs).Error

	if err != nil {
		return 0, fmt.Errorf("failed to find empty conversations: %w", err)
	}

	if len(emptyConversationIDs) == 0 {
		return 0, nil
	}

	// 删除空对话
	result := r.db.WithContext(ctx).
		Where("id IN ?", emptyConversationIDs).
		Delete(&entity.Conversation{})

	if result.Error != nil {
		return 0, fmt.Errorf("failed to cleanup empty conversations: %w", result.Error)
	}

	return result.RowsAffected, nil
}
